package ui;
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.swing.*;
import javax.swing.table.*;

import pd.*;
import services.SMSService;


public class SwissSMSClientUI extends JFrame implements Observer {
	
	private static final long serialVersionUID = 1L;
	private SwissSMSClient swissSMSClient;
	private SMSService smsservice;
	private JComboBox number = new JComboBox();
	private JTextArea message = new JTextArea();
	private JButton send = new JButton("Send");
	private JLabel status = new JLabel("Status: Ready");
	private JTable history = new JTable();
	private JMenuBar mainMenuBar = new JMenuBar();
	private JMenu fileMenu = new JMenu();
	private final Vector<String> searchcontacts = new Vector<String>();
	
	
	public SwissSMSClientUI(SwissSMSClient swissSMSClient, SMSService smsservice){
		super("Swiss SMS Client");
		this.swissSMSClient = swissSMSClient;
		this.smsservice = smsservice;
		swissSMSClient.getStorage().addObserver(this);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		getContentPane().setLayout(new BorderLayout());
		setResizable(false);
		addMenus();
		initActions();
		initHistory();
		initUI();
		initContacts();
		getRootPane().setDefaultButton(send);
		setSize(400, 500);
		setLocationRelativeTo(null);
		setVisible(true);
	}
	
	private void initActions(){
		send.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				String servicename = swissSMSClient.getSetting("service").get(0);
				Vector<String> usernamepassword = swissSMSClient.getSetting(servicename);
				String snumber = ((String) number.getEditor().getItem()); 
				if(((snumber.length() == 10 && isDigit(snumber)) || getNumber(snumber) != "") && message.getText().length() > 0 
						&& !usernamepassword.get(0).matches("") && !usernamepassword.get(1).matches("")){
					if(smsservice.doLogin(usernamepassword.get(0), usernamepassword.get(1))){
						status.setText("Status: Login successful, sending message...");
						if(snumber.length() != 10 || !isDigit(snumber)){
							snumber = getNumber(snumber);
						}
						if(smsservice.sendMessage(snumber, message.getText())){
							status.setText("Status: Message sent successfully!");
							SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd HH:mm" );
							swissSMSClient.getSetting("history").insertElementAt(df.format(new Date()) + "\\" + ((String) number.getEditor().getItem()) + "\\" + message.getText(), 0);
							swissSMSClient.getStorage().saveSettings();
							number.getEditor().setItem("");
							message.setText("");
							number.grabFocus();
						} else {
							status.setText("Status: Message couldn't be sent!");
						}
					} else {
						status.setText("Status: Login failed!");
					}
				} else if(((String) number.getEditor().getItem()).length() != 10){
					status.setText("Status: Please enter a correct number!");
					number.grabFocus();
					number.getEditor().selectAll();
				} else if(message.getText().length() == 0){
					status.setText("Status: Please enter a message!");
					message.grabFocus();
				} else if(usernamepassword.get(0).matches("") || usernamepassword.get(1).matches("")){
					status.setText("Status: No username/password specified!");
				}
			}
		});
		
		number.getEditor().getEditorComponent().addKeyListener(new KeyListener(){
			public void keyPressed(KeyEvent e) {
			}
			public void keyReleased(KeyEvent e) {	
				initContacts();
			}
			public void keyTyped(KeyEvent e) {			
			}
		});
		
	}
	
	private void initContacts(){
		searchcontacts.clear();
		String text = (String) number.getEditor().getItem();
		if(text.length() == 0){
			searchcontacts.addAll(swissSMSClient.getSetting("contacts"));
		} else if(!isDigit(text.charAt(0))){
			for(String contact : swissSMSClient.getSetting("contacts")){
				if(contact.toLowerCase().startsWith(text.toLowerCase())){
					searchcontacts.add(contact);
				}
			}
		}
	}
	
	private static boolean isDigit(char c){
		for(int i = '0'; i <= '9'; i++){
			if(i == c){
				return true;
			}
		}
		return false;
	}
	
	private static boolean isDigit(String s){
		for(int i = 0; i < s.length(); i++){
			if(!isDigit(s.charAt(i))){
				return false;
			}
		}
		return true;
	}
	
	private String getNumber(String name){
		for(String contact : swissSMSClient.getSetting("contacts")){
			if(contact.toLowerCase().startsWith(name.toLowerCase())){
				return contact.substring(contact.indexOf('\\') + 1);
			}
		}
		return "";
	}
	
	private void initHistory(){
		history.setModel(new AbstractTableModel() {
			private Vector<String> messages = swissSMSClient.getSetting("history");
			private static final long serialVersionUID = 1L;
			public int getColumnCount() {return 3;}
			public int getRowCount() {return messages.size();}
			public Object getValueAt(int row, int col) {
				String retval = messages.get(row);
				switch(col){
					case 0:
						retval = retval.substring(0, retval.indexOf('\\'));
						break;
					case 1:
						retval = retval.substring(retval.indexOf('\\')+1);
						retval = retval.substring(0, retval.indexOf('\\'));
						break;
					case 2:
						retval = retval.substring(retval.indexOf('\\')+1);
						retval = retval.substring(retval.indexOf('\\')+1);
						break;
					default:
						retval = "";
						break;
				}
				return retval;
			}
		});
		history.getColumn("A").setHeaderValue("Date");
		history.getColumn("B").setHeaderValue("Receiver");
		history.getColumn("C").setHeaderValue("Message");
	}

	private void addMenus() {
		
		fileMenu = new JMenu("File");
		JMenuItem pref = new JMenuItem("Preferences");
		pref.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				swissSMSClient.showPrefPane();
			}
		});
		fileMenu.add(pref, 0);
		
		JMenuItem addrbook = new JMenuItem("Addressbook");
		addrbook.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				swissSMSClient.showAddrBook();
			}
		});
		fileMenu.add(addrbook, 1);
		if(System.getProperty("os.name").contains("Mac OS X") && 
						swissSMSClient.getSetting("useappleaddrbook").get(0).matches("1")){
			addrbook.setEnabled(false);
		}
		
		mainMenuBar.add(fileMenu);

		setJMenuBar(mainMenuBar);
	}
	
	private void initUI(){
		
		Box inputbox = Box.createVerticalBox();
		inputbox.add(Box.createVerticalStrut(20));
		
		Box receiverbox = Box.createHorizontalBox();
		receiverbox.add(Box.createHorizontalStrut(20));
		receiverbox.add(new JLabel("Receiver:  "));
		number.setEditable(true);
		setSize(number, 200, 30);
		receiverbox.add(number);
		receiverbox.add(Box.createHorizontalGlue());
		inputbox.add(receiverbox);
		inputbox.add(Box.createVerticalStrut(10));
		number.setModel(new DefaultComboBoxModel(){
			private static final long serialVersionUID = 1L;
			public Object getElementAt(int index){
				String contact = searchcontacts.get(index);
				return contact.substring(0, contact.indexOf('\\'));
			}
			public int getSize(){
				return searchcontacts.size();
			}
		});
		
		Box messagebox = Box.createHorizontalBox();
		messagebox.add(Box.createHorizontalStrut(20));
		messagebox.add(new JLabel("Message:  "));
		message.setLineWrap(true);
		JScrollPane messageScrollPane = new JScrollPane(message);
		setSize(messageScrollPane, 300, 150);
		messagebox.add(messageScrollPane);
		messagebox.add(Box.createHorizontalGlue());
		inputbox.add(messagebox);
		inputbox.add(Box.createVerticalStrut(10));
		
		Box actionbox = Box.createHorizontalBox();
		actionbox.add(Box.createHorizontalStrut(20));
		actionbox.add(status);
		actionbox.add(Box.createHorizontalGlue());
		actionbox.add(send);
		actionbox.add(Box.createHorizontalStrut(20));
		inputbox.add(actionbox);
		inputbox.add(Box.createVerticalStrut(10));
		
		getContentPane().add(inputbox, BorderLayout.NORTH);
		JScrollPane historyScroll = new JScrollPane(history);
		setSize(historyScroll, 300, 150);
		getContentPane().add(historyScroll, BorderLayout.SOUTH);
		
	}
	
	private static void setSize(Component c, int dx, int dy){
		c.setPreferredSize(new Dimension(dx,dy));
		c.setMinimumSize(new Dimension(dx,dy));
		c.setMaximumSize(new Dimension(dx,dy));
	}

	public void update(Observable o, Object arg) {
		initHistory();
		initContacts();
		try{
			if(System.getProperty("os.name").contains("Mac OS X")){
				fileMenu.getMenuComponent(1).setEnabled(swissSMSClient.getSetting("useappleaddrbook").get(0).matches("0"));

			}
		} catch(IllegalArgumentException e){
		}
	}
}
